package com.example.demo.service;

import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson2.JSONObject;
import com.alibaba.fastjson2.TypeReference;
import com.example.demo.api.LoginApi;
import com.example.demo.dto.CheckInfo;
import com.example.demo.dto.LoginInfo;
import com.example.demo.dto.QrData;
import com.example.demo.util.FileUtil;
import com.example.demo.util.ImageUtil;
import com.example.demo.util.OkhttpUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.io.File;
import java.util.List;

/**
 * @author gsq
 * @date 2025/3/6 15:43
 */
@Slf4j
@Service
public class LoginService {

    @Value("${gewe.qrcode_timeout_cnt}")
    private Long qrCodeTimeoutCnt;
    @Value("${gewe.xueqiu_token_filepath}")
    private String xueqiuTokenFilepath;
    @Value("${gewe.token_filepath}")
    private String tokenFilepath;
    @Value("${gewe.qrcode_img_filepath}")
    private String qrCodeImgFilepath;
    @Value("${gewe.qrcode_json_filepath}")
    private String qrCodeJsonFilepath;
    @Value("${gewe.callback_url}")
    private String callbackUrl;

    public String setToken(boolean force) {
        String token;
        if (!force) {
            token = FileUtil.read(tokenFilepath);
            log.info("登录模块-获取token-读取缓存文件：{}", token);

            if (StrUtil.isNotBlank(token)) {
                Constants.token = token;
                log.info("设置token={}", token);
                return token;
            }
        }

        JSONObject jsonObject = LoginApi.getToken();
        token = jsonObject.getString("data");
        Constants.token = token;
        log.info("设置token={}", token);

        FileUtil.write(tokenFilepath, token);
        log.info("登录模块-获取token-写缓存文件：{}", token);
        return token;
    }

    public String setXueqiuToken() {
        String xqAToken = FileUtil.read(xueqiuTokenFilepath);
        log.info("登录模块-获取xqAToken-读取缓存文件：{}", xqAToken);
        if (StrUtil.isBlank(xqAToken)) {
            throw new RuntimeException("获取xqAToken失败！");
        }
        Constants.xqAToken = xqAToken;
        log.info("设置xueqiuToken={}", xqAToken);
        return xqAToken;
    }

    public String setAppId() {
        String jsonStr = null;
        try {
            jsonStr = FileUtil.read(qrCodeJsonFilepath);
        } catch (Exception e) {
            log.warn("找不到qr缓存文件：{}", qrCodeJsonFilepath);
        }

        if (StrUtil.isNotBlank(jsonStr)) {
            QrData qrData = JSONObject.parseObject(jsonStr, QrData.class);
            Constants.appId = qrData.getAppId();;
            Constants.qrImgBase64 = qrData.getQrImgBase64();
            log.info("设置appId={}, qrImgBase64={}", qrData.getAppId(), qrData.getQrImgBase64().substring(0, Math.min(100, qrData.getQrImgBase64().length())));
        }
        return Constants.appId;
    }

    public void login() {

        QrData qrData = getLoginQrCode();
        log.info("登录模块-获取登录二维码(步骤2): appId={}, uuid={}", qrData.getAppId(), qrData.getUuid());

        ImageUtil.generateImage(qrData.getQrImgBase64(), qrCodeImgFilepath);
        log.info("登录模块-获取登录二维码(步骤2)-路径：{}", qrCodeImgFilepath);

        for (int i = 0; i < qrCodeTimeoutCnt; ++i) {
            JSONObject checkQr = LoginApi.checkQr(qrData.getAppId(), qrData.getUuid(), null);
            CheckInfo checkInfo = JSONObject.parseObject(checkQr.toJSONString(), new TypeReference<CheckInfo>() {
            });
            log.info("登录模块-执行登录(步骤3)-第{}次查询：{}", i, checkInfo);
            LoginInfo loginInfo = checkInfo.getLoginInfo();
            if (loginInfo != null) {
                FileUtil.write(String.format(Constants.LOGIN_USER_FILENAME, loginInfo.getWxid()), JSONObject.toJSONString(loginInfo));
                log.info("登录模块-登录成功：{}", loginInfo);

                LoginApi.setCallback(Constants.token, callbackUrl);
                log.info("登录模块-设置回调地址成功：{}", callbackUrl);

                JSONObject deviceList = LoginApi.deviceList();
                List<String> list = JSONObject.parseObject(deviceList.toJSONString(), new TypeReference<List<String>>() {
                });
                log.info("登录模块-设备列表：{}", String.join(", ", list));
                break;
            }

            try {
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
    }

    public QrData getLoginQrCode() {
        String appId = setAppId();

        JSONObject qr = LoginApi.getQr(appId);
        QrData qrData = JSONObject.parseObject(qr.getString("data"), QrData.class);

        FileUtil.write(qrCodeJsonFilepath, JSONObject.toJSONString(qrData));
        log.info("登录模块-获取登录二维码-写缓存文件：{}", JSONObject.toJSONString(qrData));

        Constants.appId = qrData.getAppId();
        Constants.qrImgBase64 = qrData.getQrImgBase64();
        return qrData;
    }
}
